CTabPage Class

The CTabPage class extends the CWindow class and allows to create generic windows used as a tab pages of a tab control. Each page works as an independent CWindow, with all its methods and properties, and its own callback procedure. This allows to use the tab control to develop tabbed interfaces.

Constructor (CTabPage)

Creates a generic window used as a tab page of a tab control.

Methods

Name Description
hTabPage Returns the window handle of the tab page.
InsertPage Adds a tab page and creates a generic window that will be associated with the page.
ResizePage Resizes the currently selected tab page.
ResizePages Resizes all the tab pages associated with the tab control

Procedures

Name Description
AfxCTabPagePtr Returns a pointer to the CTabPage class given the handle of the tab control to which the tab page is associated and the zero-based tab index.
AfxDestroyTabPage Detroys a tab page.
AfxDestroyAllTabPages Detroys all the tab pages.
AfxResizeTabPages Resizes all the tab pages associated with a tab control.

Example

#define UNICODE
#INCLUDE ONCE "AfxNova/CWindow.inc"
USING AfxNova

DECLARE FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                           BYVAL hPrevInstance AS HINSTANCE, _
                           BYVAL pwszCmdLine AS WSTRING PTR, _
                           BYVAL nCmdShow AS LONG) AS LONG
   END wWinMain(GetModuleHandleW(NULL), NULL, wCommand(), SW_NORMAL)

CONST IDC_TAB       = 1001
CONST IDC_EDIT1     = 1002
CONST IDC_EDIT2     = 1003
CONST IDC_BTNSUBMIT = 1004
CONST IDC_COMBO     = 1005
CONST IDC_LISTBOX   = 1006

' // Forward declarations
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
DECLARE FUNCTION TabPage1_WndProc(BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
DECLARE FUNCTION TabPage2_WndProc(BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
DECLARE FUNCTION TabPage3_WndProc(BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Main
' ========================================================================================
FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                   BYVAL hPrevInstance AS HINSTANCE, _
                   BYVAL pwszCmdLine AS WSTRING PTR, _
                   BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)
   ' // Enable visual styles without including a manifest file
   AfxEnableVisualStyles

   ' // Creates the main window
   DIM pWindow AS CWindow = "MyClassName"   ' Use the name you wish
   DIM hWin AS HWND = pWindow.Create(NULL, "CWindow - Tab control", @WndProc)
   ' // Sizes it by setting the wanted width and height of its client area
   pWindow.SetClientSize(500, 350)
   ' // Centers the window
   pWindow.Center

   ' // Adds a tab control
   DIM AS LONG cx, cy
   cx = pWindow.ClientWidth - 20
   cy = pWindow.ClientHeight - 60
   DIM hTab AS HWND = pWindow.AddControl("Tab", hWin, IDC_TAB, "", 10, 10, cx, cy)
   ' // Anchor the control
   pWindow.AnchorControl(hTab, AFX_ANCHOR_HEIGHT_WIDTH)

   ' // Creates the first tab page
   DIM pTabPage1 AS CTabPage PTR = NEW CTabPage
   pTabPage1->InsertPage(hTab, 0, "Tab 1", -1, @TabPage1_WndProc)
   pTabPage1->SetBackColor(RGB_GOLD) 

   ' // Creates the second tab page
   DIM pTabPage2 AS CTabPage PTR = NEW CTabPage
   pTabPage2->InsertPage(hTab, 1, "Tab 2", -1, @TabPage2_WndProc)
   pTabPage2->SetBackColor(RGB_DARKTURQUOISE)

   ' // Creates the third tab page
   DIM pTabPage3 AS CTabPage PTR = NEW CTabPage
   pTabPage3->InsertPage(hTab, 2, "Tab 3", -1, @TabPage3_WndProc)
   pTabPage3->SetBackColor(RGB_CHARTREUSE)

   ' // Displays the first tab page
   ShowWindow pTabPage1->hTabPage, SW_SHOW
   ' // Set the focus to the first tab
   TabCtrl_SetCurFocus(hTab, 0)

   ' // Adds a button
   cx = pWindow.ClientWidth - 88
   cy = pWindow.ClientHeight - 37
   DIM hButton AS HWND = pWindow.AddControl("Button", hWin, IDCANCEL, "&Close", cx, cy, 75, 23)
   ' // Anchors the button to the bottom and the right side of the main window
   pWindow.AnchorControl(hButton, AFX_ANCHOR_BOTTOM_RIGHT)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      ' // If an application processes this message, it should return zero to continue
      ' // creation of the window. If the application returns –1, the window is destroyed
      ' // and the CreateWindowExW function returns a NULL handle.
      CASE WM_CREATE
         RETURN 0

      ' // Sent when the user selects a command item from a menu, when a control sends a
      ' // notification message to its parent window, or when an accelerator keystroke is translated.
      CASE WM_COMMAND
         SELECT CASE CBCTL(wParam, lParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN SendMessageW(hwnd, WM_CLOSE, 0, 0)
               RETURN 0
         END SELECT

      CASE WM_GETMINMAXINFO
         ' Set the pointer to the address of the MINMAXINFO structure
         DIM ptmmi AS MINMAXINFO PTR = CAST(MINMAXINFO PTR, lParam)
         ' Set the minimum and maximum sizes that can be produced by dragging the borders of the window
         DIM pWindow AS CWindow PTR = AfxCWindowPtr(hwnd)
         IF pWindow THEN
            ptmmi->ptMinTrackSize.x = 460 * pWindow->rxRatio
            ptmmi->ptMinTrackSize.y = 340 * pWindow->ryRatio
         END IF
         RETURN 0

      CASE WM_SIZE
         ' // Get the tab control handle
         DIM hTab AS HWND = GetDlgItem(hwnd, IDC_TAB)
         ' // Get a pointer to the tab page
         DIM pTabPage AS CTabPage PTR = AfxCTabPagePtr(hTab, -1)
         ' // Resize the tab pages
         IF pTabPage THEN pTabPage->ResizePages
         RETURN 0

      CASE WM_NOTIFY
         DIM pTabPage AS CTabPage PTR    ' // Tab page object reference
         DIM ptnmhdr AS NMHDR PTR        ' // Information about a notification message
         ptnmhdr = CAST(NMHDR PTR, lParam)
         SELECT CASE ptnmhdr->idFrom
            CASE IDC_TAB
               SELECT CASE ptnmhdr->code
                  CASE TCN_SELCHANGE
                     ' // Show the selected page
                     pTabPage = AfxCTabPagePtr(ptnmhdr->hwndFrom, -1)
                     IF pTabPage THEN ..ShowWindow pTabPage->hTabPage, SW_SHOW
                  CASE TCN_SELCHANGING
                     ' // Hide the current page
                     pTabPage = AfxCTabPagePtr(ptnmhdr->hwndFrom, -1)
                     IF pTabPage THEN ..ShowWindow pTabPage->hTabPage, SW_HIDE
               END SELECT
         END SELECT

        CASE WM_DESTROY
         ' // Destroy the tab pages
         DIM hTab AS HWND = GetDlgItem(hwnd, IDC_TAB)
         AfxDestroyAllTabPages(hTab)
         ' // Quit the application
         PostQuitMessage(0)
         EXIT FUNCTION

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Tab page 1 window procedure
' ========================================================================================
FUNCTION TabPage1_WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   DIM hBrush AS HBRUSH, rc AS RECT, tlb AS LOGBRUSH

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // Get a pointer to the TabPage class
         DIM pTabPage AS CTabPage PTR = AfxCTabPagePtr(GetParent(hwnd), 0)
         IF pTabPage = NULL THEN EXIT FUNCTION
         ' // Add controls to the first page
         DIM hLabel1 AS HWND = pTabPage->AddControl("Label", hwnd, -1, " First name", 15, 35, 121, 21)
         DIM hLabel2 AS HWND = pTabPage->AddControl("Label", hwnd, -1, " Last name", 15, 70, 121, 21)
         pTabPage->AddControl("Edit", hwnd, IDC_EDIT1, "", 165, 35, 186, 21)
         pTabPage->AddControl("Edit", hwnd, IDC_EDIT2, "", 165, 70, 186, 21)
         pTabPage->AddControl("Button", hwnd, IDC_BTNSUBMIT, "Submit", 340, 185, 76, 25)
         ' // Anchor the controls
         pTabPage->AnchorControl(GetDlgItem(hwnd, IDC_EDIT1), AFX_ANCHOR_WIDTH)
         pTabPage->AnchorControl(GetDlgItem(hwnd, IDC_EDIT2), AFX_ANCHOR_WIDTH)
         pTabPage->AnchorControl(GetDlgItem(hwnd, IDC_BTNSUBMIT), AFX_ANCHOR_BOTTOM_RIGHT)
         ' // Colors
         pTabPage->SetCtlColors(HLabel1, RGB_YELLOW, RGB_RED)
         pTabPage->SetCtlColors(HLabel2, RGB_YELLOW, RGB_RED)
         ' // Set the focus in the edit control
         SetFocus(GetDlgItem(hwnd, IDC_EDIT1))
         EXIT FUNCTION

      CASE WM_COMMAND
         SELECT CASE CBCTL(wParam, lParam)
            CASE IDC_BTNSUBMIT
               IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN
                  MessageBoxW(hWnd, "Submit", "Tab 1", MB_OK)
                  EXIT FUNCTION
               END IF
         END SELECT

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Tab page 2 window procedure
' ========================================================================================
FUNCTION TabPage2_WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   DIM hBrush AS HBRUSH, rc AS RECT, tlb AS LOGBRUSH

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // Get a pointer to the TabPage class
         DIM pTabPage AS CTabPage PTR = AfxCTabPagePtr(GetParent(hwnd), 1)
         IF pTabPage = NULL THEN EXIT FUNCTION
         ' // Add a combobox to the second page
         DIM hComboBox AS HWND = pTabPage->AddControl("ComboBox", hwnd, IDC_COMBO, "", 20, 20, 191, 105)
         ' // Anchor the control
         pTabPage->AnchorControl(GetDlgItem(hwnd, IDC_COMBO), AFX_ANCHOR_WIDTH)
         ' // Fill the combobox with some data
         DIM wszText AS WSTRING * 260
         FOR i AS LONG = 1 TO 9
            wszText = "Item " & RIGHT("00" & STR(i), 2)
            ComboBox_AddString(hComboBox, @wszText)
         NEXT
         ' // Select the first item in the combo box
         ComboBox_SetCursel(hComboBox, 0)
         EXIT FUNCTION

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Tab page 3 window procedure
' ========================================================================================
FUNCTION TabPage3_WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   DIM hBrush AS HBRUSH, rc AS RECT, tlb AS LOGBRUSH

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // Get a pointer to the TabPage class
         DIM pTabPage AS CTabPage PTR = AfxCTabPagePtr(GetParent(hwnd), 2)
         IF pTabPage = NULL THEN EXIT FUNCTION
         ' // Add a combobox to the third page
         DIM hListBox AS HWND = pTabPage->AddControl("ListBox", hwnd, IDC_LISTBOX)
         pTabPage->SetWindowPos hListBox, NULL, 15, 20, 161, 120, SWP_NOZORDER
         ' // Anchor the control
         pTabPage->AnchorControl(GetDlgItem(hwnd, IDC_LISTBOX), AFX_ANCHOR_WIDTH)
         ' // Fill the combobox with some data
         DIM wszText AS WSTRING * 260
         FOR i AS LONG = 1 TO 9
            wszText = "Item " & RIGHT("00" & STR(i), 2)
            ListBox_AddString(hListBox, @wszText)
         NEXT
         ' // Select the first item in the combo box
         ListBox_SetCursel(hListBox, 0)
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

InsertPage

Adds a tab page and creates a generic window that will be associated with the page.

FUNCTION InsertPage (BYVAL hTab AS HWND, BYVAL nPage AS LONG, BYREF wszTitle AS WSTRING = "", _
   BYVAL nImage AS LONG = -1, BYVAL lpfnWndProc AS WNDPROC = NULL, _
   BYVAL dwStyle AS DWORD = WS_CLIPSIBLINGS OR WS_CLIPCHILDREN, BYVAL dwExStyle AS DWORD = 0) AS HWND
Parameter Description
hTab Handle to the Tab control.
nPage The zero based position of the page to be inserted.
wszTitle Optional. The text to be displayed of the tab area.
nImage Optional. Index in the tab control’s image list, or -1 if there is no image for the tab.
lpfnWndProc Address of the window callback procedure.

Return value

The handle of the new tab page.

Usage example

' // Create a tab page
DIM pTabPage AS CTabPage PTR = NEW CTabPage
pTabPage->InsertPage(hTab, 0, "Tab 1", -1, @TabPage_WndProc)
' // Add controls to it
pTabPage->AddControl("Label", pTabPage->hTabPage, -1, "First name", 15, 15, 121, 21)
pTabPage->AddControl("Label", pTabPage->hTabPage, -1, "Last name", 15, 50, 121, 21)
pTabPage->AddControl("Edit", pTabPage->hTabPage, IDC_EDIT1, "", 165, 15, 186, 21)
pTabPage->AddControl("Edit", pTabPage->hTabPage, IDC_EDIT2, "", 165, 50, 186, 21)
pTabPage->AddControl("Button", pTabPage->hTabPage, IDC_BTNSUBMIT, "Submit", 340, 185, 76, 26, BS_DEFPUSHBUTTON)

ResizePage

Resizes the currently selected tab page,

FUNCTION ResizePage () AS BOOLEAN

ResizePages

Resizes the all the pages associated with the tab control

FUNCTION ResizePages () AS BOOLEAN

AfxCTabPagePtr

Returns a pointer to the CTabPage class given the handle of the tab control to which the tab page is associated and the zero-based tab index.

FUNCTION AfxCTabPagePtr (BYVAL hTab AS HWND, BYVAL idx AS LONG = -1) AS CTabPage PTR
Parameter Description
hTab Handle to the Tab control.
hTab Optional. Zero-based index of the tab. If this parameter is ommited, the function will return the pointer of the currently selected tab, if any.

Usage example

DIM pTabPage AS CTabPage PTR = AfxCTabPagePtr(hTab, 1)

AfxDestroyTabPage

Detroys the specified tab page.

FUNCTION AfxDestroyTabPage (BYVAL hTab AS HWND, BYVAL idx AS LONG) AS BOOLEAN
Parameter Description
hTab Handle to the Tab control.
hTab Zero-based index of the tab. If this parameter is ommited, the function will return the pointer of the currently selected tab, if any.

Return value

TRUE or FALSE.

Usage example

AfxDestroyTabPage(hTab, 1)

AfxDestroyAllTabPages

Detroys all the tab pages.

FUNCTION AfxDestroyAllTabPages (BYVAL hTab AS HWND) AS BOOLEAN
Parameter Description
hTab Handle to the Tab control.

Return value

TRUE or FALSE.

Usage example

AfxDestroyAllTabPages(hTab)

AfxResizeTabPages

Resizes all the tab pages associated with a tab control.

FUNCTION AfxResizeTabPages (BYVAL hTab AS HWND) AS BOOLEAN
Parameter Description
hTab Handle to the Tab control.

Return value

TRUE or FALSE.

Usage example

AfxResizeTabPages(hTab)